package com.ice.netty.modbus.server;

import org.springframework.stereotype.Component;

import com.ice.netty.modbus.code.ModBusMsgDecode;
import com.ice.netty.modbus.code.ModBusMsgEncode;
import com.ice.netty.modbus.config.MiiMessage;
import com.ice.netty.modbus.config.NettyTestConfig;
import com.ice.netty.modbus.data.MiiDataFactory;
import com.ice.netty.modbus.data.MiiServerDataFactory;
import com.ice.netty.modbus.handle.DefaultProcess;
import com.ice.remoting.NettyRemotingServer;
import com.ice.remoting.common.CommonConstant;
import com.ice.remoting.data.RemotingCommand;
import com.ice.remoting.exception.AbortProcessException;
import com.ice.remoting.netty.RPCHook;

import cn.hutool.core.util.ObjectUtil;
import io.netty.channel.Channel;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.MessageToByteEncoder;
import io.netty.util.Attribute;
import io.netty.util.AttributeKey;
import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class NettyTestServer extends NettyRemotingServer {

    private MiiDataFactory dataFactory = new MiiServerDataFactory();

    private NettyTestConfig  nettyTestConfig;

    public NettyTestServer(NettyTestConfig nettyTestConfig) {
        super(nettyTestConfig);
        this.nettyTestConfig = nettyTestConfig;
    }

    public void start() {
        super.start();

        this.registerDefaultProcessor(new DefaultProcess(this));

        // 设置处理请求
        this.registerRPCHook(new RPCHook() {
            @Override
            public void doBeforeRequest(Channel channel, String remoteAddr, RemotingCommand request) {
                if (MiiMessage.DEVICE_NO_COMMAND != request.getCommand() && (byte)1 != request.getCommand()) {
                    Attribute<Object> attr = channel.attr(AttributeKey.valueOf(CommonConstant.DEVICE_NO));
                    if (ObjectUtil.isEmpty(attr.get())) {
                        log.warn("连接必须先上传设备号");
                        throw new AbortProcessException(1, "连接必须先上传设备号");
                    }
                }
            }

            @Override
            public void doAfterResponse(Channel channel, String remoteAddr, RemotingCommand request,
                RemotingCommand response) {}
        });
    }

    public MiiDataFactory getDataFactory() {
        return dataFactory;
    }

    public void setCustomerUniqueIdentity(Channel channel, String customerUniqueIdentity) {
        this.getDeviceManager().setCustomerUniqueIdentity(channel, customerUniqueIdentity);
    }

    @Override
    public ByteToMessageDecoder buildDecoder() {
        return new ModBusMsgDecode();
    }

    @Override
    public MessageToByteEncoder buildEncoder() {
        return new ModBusMsgEncode();
    }
}
